package com.chenyuxin.ilp.security.auth.handler;

import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTUtil;
import com.chenyuxin.ilp.model.constant.ExpireTimeConstant;
import com.chenyuxin.ilp.model.constant.UserSuccessConstant;
import com.chenyuxin.ilp.model.enums.exception.ExceptionEnums;
import com.chenyuxin.ilp.model.pojo.Result;
import com.chenyuxin.ilp.model.vo.user.UserLoginVo;
import com.chenyuxin.ilp.util.JwtUtils;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Component
// 登录校验成功后的处理器
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
        AuthenticationSuccessHandler.super.onAuthenticationSuccess(request, response, chain, authentication);
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        Object principal = authentication.getPrincipal();
        UserLoginVo userLoginVo = null;
        Result result;
        if(!(principal instanceof UserLoginVo)){
            result = Result.fail(ExceptionEnums.SYSTEM_ERROR);
        }else {
            userLoginVo = (UserLoginVo)principal;
            result = Result.ok(UserSuccessConstant.LOGIN_SUCCESS,userLoginVo);
        }
        // 一些特殊的登录参数。比如三方登录，需要额外返回一个字段是否需要跳转的绑定已有账号页面
        Object details = authentication.getDetails();
        if (details instanceof Map) {
            Map detailsMap = (Map)details;
            result = Result.ok(UserSuccessConstant.LOGIN_SUCCESS,detailsMap);
        }
        String token = generateToken(userLoginVo, ExpireTimeConstant.TOKEN_EXPIRE_TIME);
        String refreshToken = generateToken(userLoginVo, ExpireTimeConstant.REFRESH_TOKEN_EXPIRE_TIME);
        response.setHeader("Authorization", "Bearer " + token);
        response.setHeader("Refresh-Token", refreshToken);
        // 虽然APPLICATION_JSON_UTF8_VALUE过时了，但也要用。因为Postman工具不声明utf-8编码就会出现乱码
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        PrintWriter writer = response.getWriter();
        String json = JSONUtil.toJsonStr(result);
        writer.print(json);
        writer.flush();
        writer.close();
    }
    private String generateToken(UserLoginVo user, long expireTime) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getUsername());
        claims.put("img", user.getImg());
        claims.put("phone", user.getPhone());
        return JwtUtils.generateToken(claims, expireTime);
    }
//    private String generateToken(UserLoginVo userLoginVo){
//        HashMap<String, Object> payload = this.getPayload(userLoginVo);
//        payload.put("exp",System.currentTimeMillis() + ExpireTimeConstant.TOKEN_EXPIRE_TIME);
//        String token = JWTUtil.createToken(payload, jwtKey.getBytes(StandardCharsets.UTF_8));
//        return token;
//    }
//    private String generateRefreshToken(UserLoginVo userLoginVo){
//        HashMap<String, Object> payload = this.getPayload(userLoginVo);
//        payload.put("exp",System.currentTimeMillis() + ExpireTimeConstant.REFRESH_TOKEN_EXPIRE_TIME);
//        String token = JWTUtil.createToken(payload, jwtKey.getBytes());
//        return token;
//    }
    private HashMap<String, Object> getPayload(UserLoginVo userLoginVo){
        HashMap<String, Object> payload = new HashMap<>();
        payload.put("id",userLoginVo.getId());
        payload.put("username",userLoginVo.getUsername());
        payload.put("img",userLoginVo.getImg());
        payload.put("phone",userLoginVo.getPhone());
        return payload;
    }
}
